package com.kara.woodAgent.web.ws;

/**
 * @author tzy
 * @version 1.0
 * @project wood_agent
 * @description
 * @date 2025/6/4 17:22:41
 */

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.kara.woodAgent.common.constant.BaseConst;
import com.kara.woodAgent.common.exception.BizException;
import com.kara.woodAgent.common.model.Result;
import com.kara.woodAgent.web.user.model.vo.LoginVo;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.MultiMap;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author laokou
 */
@Slf4j
public class VertxHttpServer extends AbstractVerticle {

    private final HttpServerProperties properties;

    private final Vertx vertx;

    private volatile HttpServer httpServer;

    private boolean isClosed = false;


    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private WebSocketConnectManager webSocketConnectManager;

    VertxHttpServer(Vertx vertx, HttpServerProperties properties) {
        this.vertx = vertx;
        this.properties = properties;
    }

    @Override
    public synchronized void start() {
        HttpServerOptions httpServerOptions = properties.getHttpServerOption();

        httpServer = vertx.createHttpServer(httpServerOptions);

        StpUtil.getSession();

        httpServer.webSocketHandler(serverWebSocket -> {
            if (!StrUtil.equals(serverWebSocket.path(), properties.getWsPath())) {
                serverWebSocket.close();
                return;
            }

            try {
                //打开链接
                MultiMap headers = serverWebSocket.headers();
                String token = headers.get("token");

                if (!StrUtil.isEmpty(token)) {
                    throw new BizException("未登录");
                }

                RBucket<LoginVo> bucket = redissonClient.getBucket(BaseConst.USER_LOGIN + ":" + token);
                LoginVo loginVo = bucket.get();
                if (loginVo == null) {
                    throw new BizException("未登录");
                }

                webSocketConnectManager.addConnection(loginVo, token, serverWebSocket);

            } catch (Exception e) {
                if (!serverWebSocket.isClosed()) {
                    serverWebSocket.writeTextMessage(JSON.toJSONString(Result.error(e.getMessage())));
                    serverWebSocket.close();
                }

            }


        }).listen().onComplete(completionHandler -> {
            if (isClosed) {
                return;
            }
            if (completionHandler.succeeded()) {
                log.info("【Vertx-Http-Server】 => WS服务启动成功，端口：{}", httpServer.actualPort());
            } else {
                Throwable ex = completionHandler.cause();
                log.error("【Vertx-Http-Server】 => WS服务启动失败，错误信息：{}", ex.getMessage(), ex);
            }
        });

    }


    @Override
    public synchronized void stop() {
        isClosed = true;
        httpServer.close().onComplete(result -> {
            if (result.succeeded()) {
                log.info("【Vertx-Http-Server】 => WS服务停止成功，端口：{}", httpServer.actualPort());
            } else {
                Throwable ex = result.cause();
                log.error("【Vertx-Http-Server】 => WS服务停止失败，错误信息：{}", ex.getMessage(), ex);
            }
        });
    }

    public void deploy() {
        // 部署服务
        vertx.deployVerticle(this);
    }

//
//    public void undeploy() {
//        // 停止服务
//        vertx.undeploy(this.deploymentID());
//    }


}

